package com.yc.spring.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 基于接口的动态代理 => 要求被代理对象必须实现接口
public class JDKProxy {

    // 代理方法, 传入被代理对象, 返回代理对象
    public static <T> T proxy(T obj){
        T res = (T) Proxy.newProxyInstance(
                obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy,
                                         Method method, Object[] args) throws Throwable {
                        Object res = method.invoke(obj, args);
                        System.out.println("交通便利");
                        System.out.println("购物方便");
                        System.out.println("童叟无欺");
                        return res;
                    }
                }
        );
        return res;
    }

    public static void main(String[] args) {
        人 p1 = new 房东();
        人 p2 = JDKProxy.proxy(p1);
        p2.say();
    }

    /**
     *
     * 1 代理对象与被代理对象关系
     *      JDK动态代理 : 兄弟关系
     *      CGLIB动态代理: 父子关系
     *
     * 2. JDK 要求被代理对象必须实现接口
     * 3. CGLIB 被final修饰的类无法被代理, 被final修饰的方法也不能被代理
     *
     */

}
